package com.loan.common.pdf;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @PACKAGE_NAME: com.loan.web.utils
 * @CLASSNAME: PDFUtil
 * @DEACRIPTION:
 * @AUTHOR: GuoChen
 * @DATE: 2024/7/3
 * @WEEK: 周三
 **/
@Slf4j
public class PDFUtil {

    private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
    private static SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");

    /**
     * 给pdf添加图片水印
     *
     * @param waterMar
     * @param imgpath  图片路径
     * @throws Exception
     */
    /*public static void addImgWaterMark(PdfContentByte waterMar, String imgpath) throws Exception {
        waterMar.beginText();

        PdfGState gs = new PdfGState();
        // 设置填充字体不透明度为0.4f
        gs.setFillOpacity(0.2f);
        // waterMar.setFontAndSize(FontGenerater.getFont(FontGenerater.FONT_SONTI_NAME), 40);
        // 设置透明度
        waterMar.setGState(gs);
        // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
        Image img = Image.getInstance(imgpath);
        img.setAbsolutePosition(200, 380);
        img.scaleAbsolute(200, 200);

        waterMar.addImage(img);
        // 设置水印颜色
        waterMar.setColorFill(BaseColor.GRAY);

        //结束设置
        waterMar.endText();
        waterMar.stroke();
    }

    *//**
     * 给pdf添加文字水印（平铺）
     *
     * @param waterMar
     * @param text     水印文本
     * @throws Exception
     *//*
    public static void addTextFullWaterMark(PdfContentByte waterMar, String text) throws Exception {
        waterMar.beginText();

        PdfGState gs = new PdfGState();
        // 设置填充字体不透明度为0.4f
        gs.setFillOpacity(0.2f);
        waterMar.setFontAndSize(FontGenerater.getFont(FontGenerater.FONT_SONTI_NAME), 40);
        // 设置透明度
        waterMar.setGState(gs);
        // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
        for (int x = 0; x <= 700; x += 200) {
            for (int y = 0; y <= 800; y += 200) {
                waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 35);
            }
        }

        // 设置水印颜色
        waterMar.setColorFill(BaseColor.GRAY);

        //结束设置
        waterMar.endText();
        waterMar.stroke();
    }

    *//**
     * 给pdf添加文字水印（单个）
     *
     * @param waterMar
     * @param text     水印文本
     * @throws Exception
     *//*
    public static void addTextWaterMark(PdfContentByte waterMar, String text) throws Exception {
        waterMar.beginText();

        PdfGState gs = new PdfGState();
        // 设置填充字体不透明度为0.4f
        gs.setFillOpacity(0.2f);
        waterMar.setFontAndSize(FontGenerater.getFont(FontGenerater.FONT_SONTI_NAME), 80);
        // 设置透明度
        waterMar.setGState(gs);
        // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
        waterMar.showTextAligned(Element.ALIGN_RIGHT, text, 475, 600, 45);

        // 设置水印颜色
        waterMar.setColorFill(BaseColor.GRAY);

        //结束设置
        waterMar.endText();
        waterMar.stroke();
    }

    *//**
     * 添加页眉、页脚
     *
     * @param writer
     * @param content
     * @param pagewidth
     * @param pageheight
     * @throws Exception
     *//*
    public static void addText(PdfWriter writer, String content, int pagewidth, int pageheight) throws Exception {
        PdfPTable table = new PdfPTable(1);
        table.setTotalWidth(530);
        PdfPCell cell = new PdfPCell(new Phrase(content, Excel2Pdf.getFont(FontGenerater.FONT_SONTI_NAME, 12, false)));
        cell.setBorder(0);
        // cell.setPaddingLeft(30f);
        cell.setPaddingTop(-15f);
        cell.setPaddingRight(20f);

        table.addCell(cell);
        Header event = new Header(table, pagewidth, pageheight);
        writer.setPageEvent(null);
        writer.setPageEvent(event);
    }

    //页眉事件
    private static class Header extends PdfPageEventHelper {
        public static PdfPTable header;
        public int pagewidth;
        public int pageheight;

        public Header(PdfPTable header, int pagewidth, int pageheight) {
            Header.header = header;
            this.pagewidth = pagewidth;
            this.pageheight = pageheight;
        }

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            //把页眉表格定位
            header.writeSelectedRows(0, -1, this.pagewidth, this.pageheight, writer.getDirectContent());
        }
    }*/

    /**
     * 添加图片
     *
     * @param document
     * @param imgPath
     * @param newWidth
     * @param newHeight
     * @param absoluteX
     * @param absoluteY
     * @throws IOException
     * @throws DocumentException
     */
    public static void addImg(Document document, String imgPath, float newWidth, float newHeight,
                              float absoluteX, float absoluteY) throws IOException, DocumentException {
        Image img1 = Image.getInstance(imgPath);
        img1.setAbsolutePosition(absoluteX, absoluteY);
        img1.scaleAbsolute(newWidth, newHeight);
        document.add(img1);
    }

    /**
     * 设置表格标题信息
     * @param table 表格实例
     * @param title 标题
     * @param font 字体
     * @param align 对齐方式
     * @param borderValue 边框信息
     */
    public static void getCellTitleValue(PdfPTable table, String title, Font font, Integer align, Integer borderValue) {
        /*
        // 全显示
        cell.disableBorderSide(0);
        //隐藏上边框
        cell.disableBorderSide(1);
        //隐藏下边框
        cell.disableBorderSide(2);
        //隐藏上、下边框
        cell.disableBorderSide(3);
        //隐藏左边框
        cell.disableBorderSide(4);
        //隐藏左、上边框
        cell.disableBorderSide(5);
        //隐藏左、下边框
        cell.disableBorderSide(6);
        //隐藏左、上、下边框
        cell.disableBorderSide(7);
        //隐藏右边框
        cell.disableBorderSide(8);
        //隐藏右、上边框
        cell.disableBorderSide(9);
        //隐藏右、下边框
        cell.disableBorderSide(10);
        //隐藏右、上、下边框
        cell.disableBorderSide(11);
        //隐藏左、右边框
        cell.disableBorderSide(12);//左右没了
        //隐藏上、左、右边框
        cell.disableBorderSide(13);//只剩下
        //隐藏下、左、右边框
        cell.disableBorderSide(14);//只剩上
        //隐藏全部
        cell.disableBorderSide(15);//全没了*/
        PdfPCell cell = new PdfPCell(new Paragraph(title, font));
        cell.setFixedHeight(20); // 设置高度
        cell.setHorizontalAlignment(align == null ? 0 : align); // 设置对齐方式 默认水平左对齐
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
        cell.disableBorderSide(borderValue == null ? 0 : borderValue); // 设置边框信息 默认全显示
        table.addCell(cell);
    }

    public static void getCellTitleValue(PdfPTable table, String title, Font font, Integer align, Integer borderValue, Integer height) {
        /*//隐藏上边框
        cell.disableBorderSide(1);
        //隐藏下边框
        cell.disableBorderSide(2);
        //隐藏上、下边框
        cell.disableBorderSide(3);
        //隐藏左边框
        cell.disableBorderSide(4);
        //隐藏左、上边框
        cell.disableBorderSide(5);
        //隐藏左、下边框
        cell.disableBorderSide(6);
        //隐藏左、上、下边框
        cell.disableBorderSide(7);
        //隐藏右边框
        cell.disableBorderSide(8);
        //隐藏右、上边框
        cell.disableBorderSide(9);
        //隐藏右、下边框
        cell.disableBorderSide(10);
        //隐藏右、上、下边框
        cell.disableBorderSide(11);
        //隐藏左、右边框
        cell.disableBorderSide(12);//左右没了
        //隐藏上、左、右边框
        cell.disableBorderSide(13);//只剩下
        //隐藏下、左、右边框
        cell.disableBorderSide(14);//只剩上
        //隐藏全部
        cell.disableBorderSide(15);//全没了*/
        PdfPCell cell = new PdfPCell(new Paragraph(title, font));
        cell.setFixedHeight(height == null ? 20 : height); // 设置高度
        cell.setHorizontalAlignment(align == null ? 0 : align); // 设置对齐方式 默认水平左对齐
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
        cell.disableBorderSide(borderValue == null ? 12 : borderValue); // 设置边框信息 默认只显示上下
        table.addCell(cell);
    }

    public static void getCellTitleValue(PdfPTable table, String title, Font font, Integer align, Integer borderValue, Integer height, Float width) {
        /*//隐藏上边框
        cell.disableBorderSide(1);
        //隐藏下边框
        cell.disableBorderSide(2);
        //隐藏上、下边框
        cell.disableBorderSide(3);
        //隐藏左边框
        cell.disableBorderSide(4);
        //隐藏左、上边框
        cell.disableBorderSide(5);
        //隐藏左、下边框
        cell.disableBorderSide(6);
        //隐藏左、上、下边框
        cell.disableBorderSide(7);
        //隐藏右边框
        cell.disableBorderSide(8);
        //隐藏右、上边框
        cell.disableBorderSide(9);
        //隐藏右、下边框
        cell.disableBorderSide(10);
        //隐藏右、上、下边框
        cell.disableBorderSide(11);
        //隐藏左、右边框
        cell.disableBorderSide(12);//左右没了
        //隐藏上、左、右边框
        cell.disableBorderSide(13);//只剩下
        //隐藏下、左、右边框
        cell.disableBorderSide(14);//只剩上
        //隐藏全部
        cell.disableBorderSide(15);//全没了*/
        PdfPCell cell = new PdfPCell(new Paragraph(title, font));
        cell.setFixedHeight(height == null ? 20 : height); // 设置高度
        if (width != null) {
            cell.setBorderWidth(width);
        }
        cell.setHorizontalAlignment(align == null ? 0 : align); // 设置对齐方式 默认水平左对齐
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
        cell.disableBorderSide(borderValue == null ? 12 : borderValue); // 设置边框信息 默认只显示上下
        table.addCell(cell);
    }


    /**
     * 设置表格值信息
     * @param table 表格实例
     * @param title 值内容
     * @param font 字体
     * @param border 边框信息
     * @param align 对齐方式
     */
    public static void getCellValue(PdfPTable table, String title, Font font, Integer border, Integer align) {
        PdfPCell cell = new PdfPCell(new Paragraph(title, font));
        // cell.setBorder(border == null ? 0 : border); // 设置边框 默认无边框
        cell.disableBorderSide(border == null ? 15 : border); // 设置边框信息 默认无边框
        cell.setHorizontalAlignment(align == null ? 0 : align); // 设置对齐方式 默认水平左对齐
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
        table.addCell(cell);
    }

    /**
     * 获取排序后的随机日期与随机时间
     * @param startTime 开始日期
     * @param endTime 结束日期
     * @param num 数量
     * @return
     */
    public static Map<String, List<String>> getRandomDateTimeList(String startTime, String endTime, Integer num) {
        Map<String, List<String>> map = new HashMap<>();
        List<String> randomDateList = getRandomDateList(startTime, endTime, num);
        List<String> randomTimeList = getRandomTimeList(num);
        for (int i = 0; i < randomDateList.size(); i++) {
            randomDateList.set(i, randomDateList.get(i) + "-" + randomTimeList.get(i));
        }
        List<String> randomDateSortList = randomDateList.stream().sorted().collect(Collectors.toList());
        log.info("{}", randomDateSortList);
        List<String> dateStrList = new ArrayList<>();
        List<String> timeStrList = new ArrayList<>();
        for (String dateTime : randomDateSortList) {
            String[] split = dateTime.split("-");
            dateStrList.add(split[0]);
            timeStrList.add(split[1]);
        }
        map.put("dateStrList", dateStrList);
        map.put("timeStrList", timeStrList);
        return map;
    }

    /**
     * 获取随机日期
     * @param startTime 开始日期
     * @param endTime 结束日期
     * @param num 数量
     * @return
     */
    private static List<String> getRandomDateList(String startTime, String endTime, Integer num) {
        LocalDate start = LocalDate.parse(startTime);
        LocalDate end = LocalDate.parse(endTime);
        List<String> dateStrList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            dateStrList.add(generateRandomDate(start, end));
        }
        return dateStrList;
    }

    /**
     * 获取随机时间
     * @param num 数量
     * @return
     */
    private static List<String> getRandomTimeList(Integer num) {
        List<String> timeStrList = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            timeStrList.add(getRandomTime());
        }
        return timeStrList;
    }

    private static String generateRandomDate(LocalDate startInclusive, LocalDate endExclusive) {
        long startEpochDay = startInclusive.toEpochDay();
        long endEpochDay = endExclusive.toEpochDay();
        long randomDay = startEpochDay + (long) (new Random().nextDouble() * (endEpochDay - startEpochDay));
        LocalDate randomDate = LocalDate.ofEpochDay(randomDay);
        String dateStr = dtf.format(randomDate);
        log.info(dateStr);
        return dateStr;
    }

    private static String getRandomTime() {
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        // 随机数生成器
        Random random = new Random();
        int min = 6;
        int max = 22;
        // 随机设置时分秒
        calendar.set(Calendar.HOUR_OF_DAY, random.nextInt(max - min + 1) + min); // 0到23点
        calendar.set(Calendar.MINUTE, random.nextInt(60)); // 0到59分
        calendar.set(Calendar.SECOND, random.nextInt(60)); // 0到59秒

        // 输出随机的时间
        Date time = calendar.getTime();
        String timeStr = sdf.format(time);
        log.info(timeStr);
        return timeStr;
    }

    /**
     * 获取9位随机数字(NH日志号)
     *
     * @return
     */
    public static String getRandomValue() {
        Random random = new Random();
        int randomNumber = 100000000 + random.nextInt(900000000); // 生成9位随机数
        return String.valueOf(randomNumber);
    }

    public static void main(String[] args) {
        getRandomDateTimeList("2022-02-01", "2023-03-06", 100);
    }

}
